class PlotEditor {
    constructor() {
        // 初始化编辑器状态
        this.editorState = {
            nodes: [],
            connections: [],
            selectedNodeId: null,
            selectedNodeIds: [], // 多选节点ID数组
            isCtrlPressed: false, // Ctrl键状态
            nextNodeId: 1,
            zoom: 1,
            pan: { x: 0, y: 0 },
            history: [],
            historyIndex: -1,
            projectName: 'Untitled Project',
            currentGeneratedMap: null
        };

        // 字符地图生成器相关
        this.mapGeneratorPanel = null;

        // DOM元素
        this.elements = {
            canvas: document.getElementById('editor-canvas'),
            canvasWrapper: document.getElementById('editor-canvas-wrapper'),
            zoomIn: document.getElementById('zoom-in'),
            zoomOut: document.getElementById('zoom-out'),
            resetView: document.getElementById('reset-view'),
            nodeProperties: document.getElementById('node-properties'),
            noSelection: document.getElementById('no-selection'),
            nodeName: document.getElementById('node-name'),
            dialogueProperties: document.getElementById('dialogue-properties'),
            choiceProperties: document.getElementById('choice-properties'),
            eventProperties: document.getElementById('event-properties'),
            dialogueCharacter: document.getElementById('dialogue-character'),
            dialogueText: document.getElementById('dialogue-text'),
            choicesList: document.getElementById('choices-list'),
            addChoiceOption: document.getElementById('add-choice-option'),
            eventType: document.getElementById('event-type'),
            eventDetails: document.getElementById('event-details'),
            saveNodeProperties: document.getElementById('save-node-properties'),
            newProject: document.getElementById('new-project'),
            openProject: document.getElementById('open-project'),
            saveProject: document.getElementById('save-project'),
            exportProject: document.getElementById('export-project'),
            undoAction: document.getElementById('undo-action'),
            redoAction: document.getElementById('redo-action'),
            deleteNode: document.getElementById('delete-node'),
            modal: document.getElementById('modal'),
            closeModal: document.querySelector('.close-modal'),
            modalBody: document.getElementById('modal-body'),
            components: document.querySelectorAll('.component-item')
        };

        // 初始化SVG Pan Zoom
        // 初始化SVG Pan Zoom，确保画布可平移和缩放
        this.panZoom = svgPanZoom(this.elements.canvas, {
            zoomEnabled: true,
            panEnabled: true,
            controlIconsEnabled: false,
            fit: true,
            center: true,
            minZoom: 0.5,
            maxZoom: 2
        });

        // 为项目结构添加交互
        this.initProjectTree();

        // 初始化节点连接功能
        this.initConnectionCreation();

        // 绑定事件
        this.bindEvents();

        // 初始化画布
        this.renderCanvas();
    }

    // 绑定事件
    bindEvents() {
        // 键盘事件 - Ctrl键状态
        document.addEventListener('keydown', (e) => {
            if (e.ctrlKey && !this.editorState.isCtrlPressed) {
                this.editorState.isCtrlPressed = true;
                document.body.classList.add('multi-select-mode');
            }
        });

        document.addEventListener('keyup', (e) => {
            if (!e.ctrlKey && this.editorState.isCtrlPressed) {
                this.editorState.isCtrlPressed = false;
                document.body.classList.remove('multi-select-mode');
            }
        });

        // 缩放控制
        this.elements.zoomIn.addEventListener('click', () => this.zoom(0.1));
        this.elements.zoomOut.addEventListener('click', () => this.zoom(-0.1));
        this.elements.resetView.addEventListener('click', () => this.resetCanvasView());

        // 节点属性保存
        this.elements.saveNodeProperties.addEventListener('click', () => this.saveNodeProperties());

        // 事件类型变更
        this.elements.eventType.addEventListener('change', () => this.updateEventDetails());

        // 添加选项
        this.elements.addChoiceOption.addEventListener('click', () => this.addChoiceOption());

        // 项目操作
        this.elements.newProject.addEventListener('click', () => this.newProject());
        this.elements.openProject.addEventListener('click', () => this.openProject());
        this.elements.saveProject.addEventListener('click', () => this.saveProject());
        this.elements.exportProject.addEventListener('click', () => this.exportProject());

        // 编辑操作
        this.elements.undoAction.addEventListener('click', () => this.undo());
        this.elements.redoAction.addEventListener('click', () => this.redo());
        this.elements.deleteNode.addEventListener('click', () => this.deleteSelectedNode());


        // 初始化设置操作
        document.getElementById('set-character').addEventListener('click', () => this.setCharacter());
        document.getElementById('set-scene').addEventListener('click', () => this.setScene());
        document.getElementById('set-variable').addEventListener('click', () => this.setVariable());

        // 剧情设置操作
        document.getElementById('add-dialogue').addEventListener('click', () => this.createNode('dialogue-node'));
        document.getElementById('add-choice').addEventListener('click', () => this.createNode('choice-node'));
        document.getElementById('add-event').addEventListener('click', () => this.createNode('event-node'));

        // 帮助操作
        document.getElementById('show-help').addEventListener('click', () => this.showHelp());
        document.getElementById('about-editor').addEventListener('click', () => this.aboutEditor());

        // 模态窗口
        this.elements.closeModal.addEventListener('click', () => this.closeModal());

        // 组件拖放
        this.elements.components.forEach(component => {
            component.addEventListener('click', (e) => this.createNode(e.target.dataset.type));
        });

        // 画布点击事件
        this.elements.canvas.addEventListener('click', (e) => this.handleCanvasClick(e));

        // 初始化地图生成器
        this.initMapGenerator();

        // 初始化右键菜单
        this.initContextMenu();
    }

    // 缩放画布
    zoom(amount) {
        const newZoom = Math.max(0.5, Math.min(2, this.editorState.zoom + amount));
        this.editorState.zoom = newZoom;
        this.panZoom.zoom(newZoom);
    }

    // 重置画布视图
    resetCanvasView() {
        this.editorState.zoom = 1;
        this.editorState.pan = { x: 0, y: 0 };
        
        // 添加错误处理以避免矩阵不可逆的问题
        try {
            this.panZoom.reset();
        } catch (error) {
            console.warn('Failed to reset panZoom:', error);
            // 如果reset失败，尝试手动重置视图
            this.panZoom.zoom(1);
            this.panZoom.pan({ x: 0, y: 0 });
        }
    }

    // 创建节点
    createNode(type) {
        // 获取画布中心位置
        const centerX = 500;
        const centerY = 400;

        const nodeId = `node-${this.editorState.nextNodeId++}`;
        let nodeData = null;

        switch(type) {
            case 'start-node':
                nodeData = {
                    id: nodeId,
                    type: 'start',
                    name: '开始',
                    x: centerX - 50,
                    y: 50,
                    width: 100,
                    height: 50
                };
                break;
            case 'dialogue-node':
                nodeData = {
                    id: nodeId,
                    type: 'dialogue',
                    name: '对话',
                    x: centerX - 100,
                    y: centerY - 50,
                    width: 200,
                    height: 100,
                    character: '',
                    text: ''
                };
                break;
            case 'choice-node':
                nodeData = {
                    id: nodeId,
                    type: 'choice',
                    name: '选项',
                    x: centerX - 100,
                    y: centerY - 50,
                    width: 200,
                    height: 100,
                    choices: []
                };
                break;
            case 'event-node':
                nodeData = {
                    id: nodeId,
                    type: 'event',
                    name: '事件',
                    x: centerX - 100,
                    y: centerY - 50,
                    width: 200,
                    height: 100,
                    eventType: 'item',
                    eventDetails: {}
                };
                break;
            case 'end-node':
                nodeData = {
                    id: nodeId,
                    type: 'end',
                    name: '结束',
                    x: centerX - 50,
                    y: 700,
                    width: 100,
                    height: 50
                };
                break;
        }

        if (nodeData) {
            this.addHistoryState();
            this.editorState.nodes.push(nodeData);
            this.renderCanvas();
        }
    }

    // 渲染画布
    renderCanvas() {
        // 清空画布
        while (this.elements.canvas.firstChild) {
            this.elements.canvas.removeChild(this.elements.canvas.firstChild);
        }

        // 绘制连接线
        this.editorState.connections.forEach(connection => {
            this.renderConnection(connection);
        });

        // 绘制节点
        this.editorState.nodes.forEach(node => {
            this.renderNode(node);
        });
    }

    // 渲染节点
    renderNode(node) {
        // 创建组
        const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
        const isSelected = this.editorState.selectedNodeIds.includes(node.id);
        g.setAttribute('class', `node ${isSelected ? 'selected' : ''}`);
        g.setAttribute('id', node.id);
        g.setAttribute('transform', `translate(${node.x}, ${node.y})`);
        g.dataset.nodeId = node.id;

        // 创建矩形
        const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
        rect.setAttribute('width', node.width);
        rect.setAttribute('height', node.height);

        // 根据节点类型设置不同颜色
        let fillColor = '#1a1a1a';
        switch(node.type) {
            case 'start':
                fillColor = '#2a4d2a';
                break;
            case 'dialogue':
                fillColor = '#1a1a4d';
                break;
            case 'choice':
                fillColor = '#4d1a4d';
                break;
            case 'event':
                fillColor = '#4d3a1a';
                break;
            case 'end':
                fillColor = '#4d1a1a';
                break;
        }

        rect.setAttribute('fill', fillColor);
        rect.setAttribute('stroke', '#333');
        rect.setAttribute('stroke-width', '2');
        rect.setAttribute('rx', '5');
        rect.setAttribute('ry', '5');

        // 创建文本
        const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        text.setAttribute('x', node.width / 2);
        text.setAttribute('y', node.height / 2);
        text.textContent = node.name;

        // 添加到组
        g.appendChild(rect);
        g.appendChild(text);

        // 添加到画布
        this.elements.canvas.appendChild(g);

        // 添加拖拽功能
        this.makeNodeDraggable(g, node);

        // 添加点击事件
        g.addEventListener('click', (e) => {
            e.stopPropagation();
            this.selectNode(node.id);
        });

        // 添加双击事件以创建连接
        g.addEventListener('dblclick', (e) => {
            e.stopPropagation();
            this.enableNodeConnection(node.id);
            this.showMessage('点击目标节点以创建连接');
        });

        // 添加右键菜单事件
        g.addEventListener('contextmenu', (e) => {
            e.preventDefault();
            e.stopPropagation();
            
            // 选择当前节点
            this.selectNode(node.id);
            
            // 显示右键菜单
            const contextMenu = document.getElementById('context-menu');
            contextMenu.style.display = 'block';
            contextMenu.style.left = e.clientX + 'px';
            contextMenu.style.top = e.clientY + 'px';
            
            // 存储当前节点ID供菜单项使用
            contextMenu.dataset.nodeId = node.id;
        });
    }

    // 渲染连接线
    renderConnection(connection) {
        const startNode = this.editorState.nodes.find(n => n.id === connection.from);
        const endNode = this.editorState.nodes.find(n => n.id === connection.to);

        if (!startNode || !endNode) return;

        // 计算连接线的起点和终点
        const startX = startNode.x + startNode.width / 2;
        const startY = startNode.y + startNode.height;
        const endX = endNode.x + endNode.width / 2;
        const endY = endNode.y;

        // 创建路径
        const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
        path.setAttribute('class', 'connection');

        // 创建贝塞尔曲线
        const controlY1 = startY + 50;
        const controlY2 = endY - 50;
        const d = `M ${startX} ${startY} C ${startX} ${controlY1}, ${endX} ${controlY2}, ${endX} ${endY}`;
        path.setAttribute('d', d);

        // 创建箭头
        const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
        marker.setAttribute('id', `arrow-${connection.id}`);
        marker.setAttribute('viewBox', '0 0 10 10');
        marker.setAttribute('refX', '9');
        marker.setAttribute('refY', '5');
        marker.setAttribute('markerWidth', '6');
        marker.setAttribute('markerHeight', '6');
        marker.setAttribute('orient', 'auto');

        const arrowPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
        arrowPath.setAttribute('d', 'M 0 0 L 10 5 L 0 10 z');
        arrowPath.setAttribute('class', 'connection-arrow');

        marker.appendChild(arrowPath);
        this.elements.canvas.appendChild(marker);

        path.setAttribute('marker-end', `url(#arrow-${connection.id})`);

        // 添加到画布
        this.elements.canvas.appendChild(path);
    }

    // 使节点可拖拽
    makeNodeDraggable(g, node) {
        let isDragging = false;
        let offsetX, offsetY;

        g.addEventListener('mousedown', (e) => {
            e.stopPropagation();
            isDragging = true;
            const pt = this.getSVGPoint(e);
            offsetX = pt.x - node.x;
            offsetY = pt.y - node.y;
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;
            e.preventDefault();
            const pt = this.getSVGPoint(e);
            this.addHistoryState();
            node.x = pt.x - offsetX;
            node.y = pt.y - offsetY;
            this.renderCanvas();
        });

        document.addEventListener('mouseup', () => {
            isDragging = false;
        });
    }

    // 获取SVG坐标
    getSVGPoint(event) {
        const pt = this.elements.canvas.createSVGPoint();
        pt.x = event.clientX;
        pt.y = event.clientY;
        
        // 获取变换矩阵
        const ctm = this.elements.canvas.getScreenCTM();
        
        // 检查矩阵是否可逆
        if (!ctm) {
            // 如果无法获取CTM，返回原始点
            return pt;
        }
        
        try {
            return pt.matrixTransform(ctm.inverse());
        } catch (error) {
            // 如果矩阵不可逆，返回原始点
            console.warn('Matrix is not invertible:', error);
            return pt;
        }
    }

    // 选择节点
    selectNode(nodeId) {
        if (this.editorState.isCtrlPressed) {
            // Ctrl按下时进行多选
            const index = this.editorState.selectedNodeIds.indexOf(nodeId);
            if (index > -1) {
                // 如果已选中，则取消选择
                this.editorState.selectedNodeIds.splice(index, 1);
            } else {
                // 否则添加到选中列表
                this.editorState.selectedNodeIds.push(nodeId);
            }
            
            // 更新主选中的节点ID
            this.editorState.selectedNodeId = this.editorState.selectedNodeIds.length > 0 ? 
                this.editorState.selectedNodeIds[this.editorState.selectedNodeIds.length - 1] : null;
        } else {
            // 普通点击，单选
            this.editorState.selectedNodeIds = [nodeId];
            this.editorState.selectedNodeId = nodeId;
        }
        
        this.renderCanvas();
        this.updatePropertiesPanel();
    }

    // 更新属性面板
    updatePropertiesPanel() {
        if (this.editorState.selectedNodeIds.length === 0) {
            this.elements.nodeProperties.classList.add('hidden');
            this.elements.noSelection.classList.remove('hidden');
            return;
        }

        this.elements.nodeProperties.classList.remove('hidden');
        this.elements.noSelection.classList.add('hidden');

        // 多选时显示批量操作信息
        if (this.editorState.selectedNodeIds.length > 1) {
            // 创建批量操作容器
            const batchContainer = document.createElement('div');
            batchContainer.id = 'batch-operation-panel';
            batchContainer.innerHTML = `
                <h3>批量操作 (${this.editorState.selectedNodeIds.length} 个节点)</h3>
                <div class="property-group">
                    <p>已选择 ${this.editorState.selectedNodeIds.length} 个节点</p>
                    <button id="delete-selected-nodes" class="btn btn-danger">删除选中节点</button>
                </div>
            `;
            
            // 隐藏原有属性面板内容
            const originalContent = this.elements.nodeProperties.querySelector('.property-group, #dialogue-properties, #choice-properties, #event-properties, button');
            if (originalContent) {
                // 保存原有内容
                if (!this._originalNodePropertiesContent) {
                    this._originalNodePropertiesContent = this.elements.nodeProperties.innerHTML;
                }
                
                // 清空并添加批量操作内容
                this.elements.nodeProperties.innerHTML = '';
                this.elements.nodeProperties.appendChild(batchContainer);
                
                // 绑定删除按钮事件
                const deleteBtn = document.getElementById('delete-selected-nodes');
                if (deleteBtn) {
                    deleteBtn.addEventListener('click', () => this.deleteSelectedNode());
                }
            }
            return;
        }

        // 单选时显示节点属性
        const node = this.editorState.nodes.find(n => n.id === this.editorState.selectedNodeId);
        if (!node) return;

        // 恢复原有内容（如果存在）
        if (this._originalNodePropertiesContent) {
            this.elements.nodeProperties.innerHTML = this._originalNodePropertiesContent;
            this._originalNodePropertiesContent = null;
        }

        // 重新获取DOM引用
        this.elements.nodeName = document.getElementById('node-name');
        this.elements.dialogueProperties = document.getElementById('dialogue-properties');
        this.elements.dialogueCharacter = document.getElementById('dialogue-character');
        this.elements.dialogueText = document.getElementById('dialogue-text');
        this.elements.choiceProperties = document.getElementById('choice-properties');
        this.elements.choicesList = document.getElementById('choices-list');
        this.elements.eventProperties = document.getElementById('event-properties');
        this.elements.eventType = document.getElementById('event-type');
        this.elements.eventDetails = document.getElementById('event-details');
        this.elements.saveNodeProperties = document.getElementById('save-node-properties');

        // 重新绑定事件
        if (this.elements.saveNodeProperties) {
            this.elements.saveNodeProperties.addEventListener('click', () => this.saveNodeProperties());
        }
        const addChoiceBtn = document.getElementById('add-choice-option');
        if (addChoiceBtn) {
            addChoiceBtn.addEventListener('click', () => this.addChoiceOption());
        }
        if (this.elements.eventType) {
            this.elements.eventType.addEventListener('change', () => {
                const node = this.editorState.nodes.find(n => n.id === this.editorState.selectedNodeId);
                if (node) {
                    this.updateEventDetails(node.eventDetails);
                }
            });
        }

        // 隐藏所有属性组
        if (this.elements.dialogueProperties) this.elements.dialogueProperties.classList.add('hidden');
        if (this.elements.choiceProperties) this.elements.choiceProperties.classList.add('hidden');
        if (this.elements.eventProperties) this.elements.eventProperties.classList.add('hidden');

        // 设置节点名称
        if (this.elements.nodeName) this.elements.nodeName.value = node.name || '';

        // 根据节点类型显示相应属性
        switch(node.type) {
            case 'dialogue':
                if (this.elements.dialogueProperties) this.elements.dialogueProperties.classList.remove('hidden');
                if (this.elements.dialogueCharacter) this.elements.dialogueCharacter.value = node.character || '';
                if (this.elements.dialogueText) this.elements.dialogueText.value = node.text || '';
                break;
            case 'choice':
                if (this.elements.choiceProperties) this.elements.choiceProperties.classList.remove('hidden');
                this.renderChoicesList(node.choices);
                break;
            case 'event':
                if (this.elements.eventProperties) this.elements.eventProperties.classList.remove('hidden');
                if (this.elements.eventType) this.elements.eventType.value = node.eventType || 'item';
                this.updateEventDetails(node.eventDetails);
                break;
        }
    }

    // 渲染选项列表
    renderChoicesList(choices) {
        this.elements.choicesList.innerHTML = '';

        if (!choices || choices.length === 0) {
            this.addChoiceOption();
            return;
        }

        choices.forEach((choice, index) => {
            const choiceDiv = document.createElement('div');
            choiceDiv.className = 'choice-option';

            const label = document.createElement('label');
            label.textContent = `选项 ${index + 1}:`;

            const input = document.createElement('input');
            input.type = 'text';
            input.value = choice.text || '';
            input.placeholder = '输入选项文本...';
            input.dataset.index = index;

            const deleteBtn = document.createElement('button');
            deleteBtn.textContent = '删除';
            deleteBtn.dataset.index = index;
            deleteBtn.addEventListener('click', (e) => {
                const idx = parseInt(e.target.dataset.index);
                this.addHistoryState();
                const node = this.editorState.nodes.find(n => n.id === this.editorState.selectedNodeId);
                if (node && node.choices) {
                    node.choices.splice(idx, 1);
                    this.renderChoicesList(node.choices);
                }
            });

            choiceDiv.appendChild(label);
            choiceDiv.appendChild(input);
            choiceDiv.appendChild(deleteBtn);
            this.elements.choicesList.appendChild(choiceDiv);
        });
    }

    // 添加选项
    addChoiceOption() {
        const node = this.editorState.nodes.find(n => n.id === this.editorState.selectedNodeId);
        if (!node || node.type !== 'choice') return;

        this.addHistoryState();
        if (!node.choices) node.choices = [];
        node.choices.push({ text: '', nextNodeId: null });
        this.renderChoicesList(node.choices);
    }

    // 更新事件详情
    updateEventDetails(details = {}) {
        const eventType = this.elements.eventType.value;
        this.elements.eventDetails.innerHTML = '';

        switch(eventType) {
            case 'item':
                this.elements.eventDetails.innerHTML = `
                    <div class="property-group">
                        <label for="item-name">物品名称:</label>
                        <input type="text" id="item-name" value="${details.name || ''}">
                    </div>
                    <div class="property-group">
                        <label for="item-description">物品描述:</label>
                        <textarea id="item-description">${details.description || ''}</textarea>
                    </div>
                    <button id="map-design-btn" class="btn">设计字符地图</button>
                `;
                break;
            case 'variable':
                this.elements.eventDetails.innerHTML = `
                    <div class="property-group">
                        <label for="variable-name">变量名称:</label>
                        <input type="text" id="variable-name" value="${details.name || ''}">
                    </div>
                    <div class="property-group">
                        <label for="variable-value">变量值:</label>
                        <input type="text" id="variable-value" value="${details.value || ''}">
                    </div>
                `;
                break;
            case 'scene':
                this.elements.eventDetails.innerHTML = `
                    <div class="property-group">
                        <label for="scene-name">场景名称:</label>
                        <input type="text" id="scene-name" value="${details.name || ''}">
                    </div>
                    <button id="map-design-btn" class="btn">设计字符地图</button>
                `;
                break;
            case 'branch':
                this.elements.eventDetails.innerHTML = `
                    <div class="property-group">
                        <label for="branch-condition">条件:</label>
                        <textarea id="branch-condition">${details.condition || ''}</textarea>
                    </div>
                `;
                break;
        }

        // 为地图设计按钮绑定事件
        const mapDesignBtn = document.getElementById('map-design-btn');
        if (mapDesignBtn) {
            mapDesignBtn.addEventListener('click', () => {
                this.showMapGeneratorPanel();
            });
        }
    }

    // 保存节点属性
    saveNodeProperties() {
        if (!this.editorState.selectedNodeId) return;

        const node = this.editorState.nodes.find(n => n.id === this.editorState.selectedNodeId);
        if (!node) return;

        this.addHistoryState();

        // 更新节点名称
        node.name = this.elements.nodeName.value;

        // 根据节点类型更新属性
        switch(node.type) {
            case 'dialogue':
                node.character = this.elements.dialogueCharacter.value;
                node.text = this.elements.dialogueText.value;
                break;
            case 'choice':
                const choices = [];
                document.querySelectorAll('#choices-list .choice-option input').forEach(input => {
                    const index = parseInt(input.dataset.index);
                    choices[index] = { text: input.value, nextNodeId: node.choices[index]?.nextNodeId || null };
                });
                node.choices = choices;
                break;
            case 'event':
                node.eventType = this.elements.eventType.value;
                const eventDetails = {};

                switch(node.eventType) {
                    case 'item':
                        eventDetails.name = document.getElementById('item-name').value;
                        eventDetails.description = document.getElementById('item-description').value;
                        break;
                    case 'variable':
                        eventDetails.name = document.getElementById('variable-name').value;
                        eventDetails.value = document.getElementById('variable-value').value;
                        break;
                    case 'scene':
                        eventDetails.name = document.getElementById('scene-name').value;
                        break;
                    case 'branch':
                        eventDetails.condition = document.getElementById('branch-condition').value;
                        break;
                }

                node.eventDetails = eventDetails;
                break;
        }

        this.renderCanvas();
    }

    // 添加历史状态
    addHistoryState() {
        // 移除当前状态之后的历史
        if (this.editorState.historyIndex < this.editorState.history.length - 1) {
            this.editorState.history = this.editorState.history.slice(0, this.editorState.historyIndex + 1);
        }

        // 保存当前状态的深拷贝
        const currentState = {
            nodes: JSON.parse(JSON.stringify(this.editorState.nodes)),
            connections: JSON.parse(JSON.stringify(this.editorState.connections)),
            selectedNodeId: this.editorState.selectedNodeId
        };

        this.editorState.history.push(currentState);
        this.editorState.historyIndex = this.editorState.history.length - 1;
    }

    // 撤销
    undo() {
        if (this.editorState.historyIndex > 0) {
            this.editorState.historyIndex--;
            const prevState = this.editorState.history[this.editorState.historyIndex];
            this.editorState.nodes = prevState.nodes;
            this.editorState.connections = prevState.connections;
            this.editorState.selectedNodeId = prevState.selectedNodeId;
            this.renderCanvas();
            this.updatePropertiesPanel();
        }
    }

    // 重做
    redo() {
        if (this.editorState.historyIndex < this.editorState.history.length - 1) {
            this.editorState.historyIndex++;
            const nextState = this.editorState.history[this.editorState.historyIndex];
            this.editorState.nodes = nextState.nodes;
            this.editorState.connections = nextState.connections;
            this.editorState.selectedNodeId = nextState.selectedNodeId;
            this.renderCanvas();
            this.updatePropertiesPanel();
        }
    }

    // 删除选中的节点
    deleteSelectedNode() {
        if (this.editorState.selectedNodeIds.length === 0) return;

        this.addHistoryState();

        // 删除所有选中的节点
        this.editorState.nodes = this.editorState.nodes.filter(n => !this.editorState.selectedNodeIds.includes(n.id));

        // 删除相关连接
        this.editorState.connections = this.editorState.connections.filter(c => 
            !this.editorState.selectedNodeIds.includes(c.from) && !this.editorState.selectedNodeIds.includes(c.to)
        );

        this.editorState.selectedNodeIds = [];
        this.editorState.selectedNodeId = null;
        this.renderCanvas();
        this.updatePropertiesPanel();
    }

    // 处理画布点击
    handleCanvasClick(e) {
        if (!this.editorState.isCtrlPressed) {
            // 非Ctrl点击时清空选择
            this.editorState.selectedNodeIds = [];
            this.editorState.selectedNodeId = null;
        }
        this.renderCanvas();
        this.updatePropertiesPanel();
    }

    // 新建项目
    newProject() {
        console.log('新建项目功能被调用');
        if (confirm('确定要创建新项目吗？当前项目未保存的内容将会丢失。')) {
            console.log('用户确认创建新项目');
            this.editorState = {
                nodes: [],
                connections: [],
                selectedNodeId: null,
                selectedNodeIds: [],
                isCtrlPressed: false,
                nextNodeId: 1,
                zoom: 1,
                pan: { x: 0, y: 0 },
                history: [],
                historyIndex: -1,
                projectName: 'Untitled Project'
            };
            this.resetCanvasView();
            this.renderCanvas();
            this.updatePropertiesPanel();
            console.log('新项目创建完成');
        } else {
            console.log('用户取消创建新项目');
        }
    }

    // 打开项目
    openProject() {
        console.log('打开项目功能被调用');
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = '.json';
        input.onchange = (e) => {
            console.log('文件选择完成');
            const file = e.target.files[0];
            if (file) {
                console.log('选中文件:', file.name);
                const reader = new FileReader();
                reader.onload = (event) => {
                    try {
                        console.log('文件读取完成');
                        const projectData = JSON.parse(event.target.result);
                        console.log('项目数据解析完成:', projectData);
                        this.editorState.nodes = projectData.nodes || [];
                        this.editorState.connections = projectData.connections || [];
                        this.editorState.nextNodeId = projectData.nextNodeId || 1;
                        this.editorState.projectName = projectData.projectName || 'Untitled Project';
                        this.editorState.history = [];
                        this.editorState.historyIndex = -1;
                        this.addHistoryState();
                        this.resetCanvasView();
                        this.renderCanvas();
                        this.updatePropertiesPanel();
                        console.log('项目加载完成');
                    } catch (error) {
                        console.error('项目文件解析错误:', error);
                        this.showMessage('项目文件格式无效: ' + error.message);
                    }
                };
                reader.onerror = (error) => {
                    console.error('文件读取错误:', error);
                    this.showMessage('文件读取失败: ' + error.message);
                };
                reader.readAsText(file);
            } else {
                console.log('未选择文件');
            }
        };
        input.click();
    }

    // 保存项目
    saveProject() {
        const projectData = {
            projectName: this.editorState.projectName,
            nodes: this.editorState.nodes,
            connections: this.editorState.connections,
            nextNodeId: this.editorState.nextNodeId
        };

        const dataStr = JSON.stringify(projectData, null, 2);
        const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);

        const exportFileDefaultName = `${this.editorState.projectName || 'untitled'}.json`;

        const linkElement = document.createElement('a');
        linkElement.setAttribute('href', dataUri);
        linkElement.setAttribute('download', exportFileDefaultName);
        linkElement.click();
        
        // 提供用户反馈
        this.showMessage(`项目 "${this.editorState.projectName}" 已保存`);
    }

    // 导出剧情
    exportProject() {
        // 构建剧情数据结构
        const plotData = {
            projectName: this.editorState.projectName,
            nodes: this.editorState.nodes,
            connections: this.editorState.connections
        };

        // 转换为文本格式
        let textContent = `# ${this.editorState.projectName || '未命名剧情'}\n\n`;

        // 按节点ID排序
        const sortedNodes = [...this.editorState.nodes].sort((a, b) => {
            const idA = parseInt(a.id.replace('node-', ''));
            const idB = parseInt(b.id.replace('node-', ''));
            return idA - idB;
        });

        // 添加节点内容
        sortedNodes.forEach(node => {
            textContent += `## ${node.name} (${node.type})\n`;
            textContent += `ID: ${node.id}\n`;

            switch(node.type) {
                case 'dialogue':
                    textContent += `角色: ${node.character}\n`;
                    textContent += `对话: ${node.text}\n`;
                    break;
                case 'choice':
                    textContent += `选项:\n`;
                    node.choices.forEach((choice, index) => {
                        textContent += `  ${index + 1}. ${choice.text}\n`;
                    });
                    break;
                case 'event':
                    textContent += `事件类型: ${node.eventType}\n`;
                    textContent += `事件详情:\n`;
                    for (const [key, value] of Object.entries(node.eventDetails)) {
                        textContent += `  ${key}: ${value}\n`;
                    }
                    // 导出地图内容
                    if (node.mapContent) {
                        textContent += `地图内容:\n${node.mapContent}\n`;
                    }
                    break;
            }

            textContent += '\n';
        });

        // 添加连接信息
        textContent += `## 剧情流程\n`;
        this.editorState.connections.forEach(connection => {
            const fromNode = this.editorState.nodes.find(n => n.id === connection.from);
            const toNode = this.editorState.nodes.find(n => n.id === connection.to);

            if (fromNode && toNode) {
                textContent += `${fromNode.name} -> ${toNode.name}\n`;
            }
        });

        // 添加全局信息
        textContent += `## 全局信息\n`;
        textContent += `节点数量: ${this.editorState.nodes.length}\n`;
        textContent += `连接数量: ${this.editorState.connections.length}\n`;
        textContent += `导出时间: ${new Date().toLocaleString()}\n`;

        // 导出为TXT文件
        const dataStr = textContent;
        const dataUri = 'data:text/plain;charset=utf-8,'+ encodeURIComponent(dataStr);

        const exportFileDefaultName = `${this.editorState.projectName || 'untitled'}.txt`;

        const linkElement = document.createElement('a');
        linkElement.setAttribute('href', dataUri);
        linkElement.setAttribute('download', exportFileDefaultName);
        linkElement.click();
    }

    // 打开模态窗口
    openModal(title, content) {
        this.elements.modalBody.innerHTML = `
            <h2>${title}</h2>
            <div>${content}</div>
        `;
        this.elements.modal.classList.remove('hidden');
    }

    // 显示消息弹窗
    showMessage(message) {
        this.openModal('提示', `<p>${message}</p>`);
    }

    // 关闭模态窗口
    closeModal() {
        this.elements.modal.classList.add('hidden');
    }

    // 初始化项目结构交互
    initProjectTree() {
        const treeItems = document.querySelectorAll('#project-tree .tree-item');
        treeItems.forEach(item => {
            item.addEventListener('click', (e) => {
                const type = e.target.dataset.type;
                this.showMessage(`项目结构: ${type} 被点击`);
                // 这里可以添加具体的项目结构交互逻辑
            });
        });
    }

    // 初始化节点连接创建功能
    initConnectionCreation() {
        this.isCreatingConnection = false;
        this.sourceNodeId = null;

        // 为节点添加连接起点事件
        this.elements.canvas.addEventListener('click', (e) => {
            if (this.isCreatingConnection && this.sourceNodeId) {
                const targetNode = e.target.closest('.node');
                if (targetNode && targetNode.dataset.nodeId !== this.sourceNodeId) {
                    this.createConnection(this.sourceNodeId, targetNode.dataset.nodeId);
                }
                this.isCreatingConnection = false;
                this.sourceNodeId = null;
                // 重置鼠标样式
                document.body.style.cursor = 'default';
            }
        });
    }

    // 创建节点连接
    createConnection(fromNodeId, toNodeId) {
        const connectionId = `connection-${Date.now()}`;
        const newConnection = {
            id: connectionId,
            from: fromNodeId,
            to: toNodeId
        };

        this.editorState.connections.push(newConnection);
        this.renderCanvas();
        this.addHistoryState();
    }

    // 为节点添加连接功能
    enableNodeConnection(nodeId) {
        this.isCreatingConnection = true;
        this.sourceNodeId = nodeId;
        // 改变鼠标样式表示正在创建连接
        document.body.style.cursor = 'crosshair';
    }

    // 初始化右键菜单
    initContextMenu() {
        // 获取右键菜单项
        const connectItem = document.getElementById('context-connect');
        const deleteItem = document.getElementById('context-delete');
        const propertiesItem = document.getElementById('context-properties');
        
        // 连接节点
        connectItem.addEventListener('click', (e) => {
            e.stopPropagation();
            const contextMenu = document.getElementById('context-menu');
            const nodeId = contextMenu.dataset.nodeId;
            if (nodeId) {
                this.enableNodeConnection(nodeId);
                this.showMessage('点击目标节点以创建连接');
                contextMenu.style.display = 'none';
            }
        });
        
        // 删除节点
        deleteItem.addEventListener('click', (e) => {
            e.stopPropagation();
            const contextMenu = document.getElementById('context-menu');
            const nodeId = contextMenu.dataset.nodeId;
            if (nodeId) {
                if (confirm('确定要删除这个节点吗？')) {
                    this.editorState.nodes = this.editorState.nodes.filter(node => node.id !== nodeId);
                    // 同时删除与该节点相关的连接
                    this.editorState.connections = this.editorState.connections.filter(
                        conn => conn.from !== nodeId && conn.to !== nodeId
                    );
                    this.editorState.selectedNodeId = null;
                    this.renderCanvas();
                    this.updatePropertiesPanel();
                    this.addHistoryState();
                }
                contextMenu.style.display = 'none';
            }
        });
        
        // 节点属性
        propertiesItem.addEventListener('click', (e) => {
            e.stopPropagation();
            const contextMenu = document.getElementById('context-menu');
            contextMenu.style.display = 'none';
            // 节点属性已经在选择节点时显示在右侧面板
            // 这里可以添加其他属性操作
        });
        
        // 点击画布其他地方隐藏右键菜单
        document.addEventListener('click', (e) => {
            if (!e.target.closest('#context-menu')) {
                document.getElementById('context-menu').style.display = 'none';
            }
        });
    }

    // 初始化地图生成器
    initMapGenerator() {
        // 创建地图生成器面板
        this.mapGeneratorPanel = document.createElement('div');
        this.mapGeneratorPanel.id = 'map-generator-panel';
        this.mapGeneratorPanel.className = 'hidden';
        this.mapGeneratorPanel.innerHTML = `
            <h3>字符地图智能设计</h3>
            <div class="form-group">
                <label for="map-width">地图宽度:</label>
                <input type="number" id="map-width" min="10" max="100" value="30">
            </div>
            <div class="form-group">
                <label for="map-height">地图高度:</label>
                <input type="number" id="map-height" min="10" max="100" value="20">
            </div>
            <div class="form-group">
                <label for="map-type">地图类型:</label>
                <select id="map-type">
                    <option value="classroom">教室</option>
                    <option value="corridor">走廊</option>
                    <option value="library">图书馆</option>
                    <option value="dormitory">宿舍</option>
                    <option value="canteen">食堂</option>
                    <option value="storageRoom">仓库</option>
                    <option value="labyrinth">迷宫</option>
                </select>
            </div>
            <div class="form-group">
                <label for="ai-api-key">硅基流动AI API Key:</label>
                <input type="password" id="ai-api-key" placeholder="输入API Key">
            </div>
            <button id="generate-map-btn" class="btn">生成地图</button>
            <button id="cancel-map-btn" class="btn">取消</button>
            <div id="map-preview-container">
                <pre id="map-preview"></pre>
            </div>
            <button id="add-map-to-node-btn" class="btn hidden">添加到节点</button>
        `;

        // 添加到属性面板容器
        const propertyPanelContainer = document.getElementById('node-properties');
        propertyPanelContainer.parentNode.appendChild(this.mapGeneratorPanel);

        // 绑定事件
        document.getElementById('generate-map-btn').addEventListener('click', () => this.generateMap());
        document.getElementById('cancel-map-btn').addEventListener('click', () => this.hideMapGeneratorPanel());
        document.getElementById('add-map-to-node-btn').addEventListener('click', () => this.addMapToNode());
    }

    // 显示地图生成器面板
    showMapGeneratorPanel() {
        this.elements.nodeProperties.classList.add('hidden');
        this.mapGeneratorPanel.classList.remove('hidden');
    }

    // 隐藏地图生成器面板
    hideMapGeneratorPanel() {
        this.mapGeneratorPanel.classList.add('hidden');
        this.elements.nodeProperties.classList.remove('hidden');
    }

    // 角色设置
    setCharacter() {
        this.openModal('角色设置', `
            <div class="form-group">
                <label for="character-name">角色名称:</label>
                <input type="text" id="character-name" placeholder="输入角色名称">
            </div>
            <div class="form-group">
                <label for="character-description">角色描述:</label>
                <textarea id="character-description" placeholder="输入角色描述"></textarea>
            </div>
            <div class="form-group">
                <label for="character-sprite">角色形象:</label>
                <input type="text" id="character-sprite" placeholder="输入角色形象代码">
            </div>
            <button id="save-character-btn" class="btn">保存角色</button>
        `);
        
        // 绑定保存按钮事件
        setTimeout(() => {
            document.getElementById('save-character-btn').addEventListener('click', () => {
                const name = document.getElementById('character-name').value;
                const description = document.getElementById('character-description').value;
                const sprite = document.getElementById('character-sprite').value;
                
                // 这里可以添加保存角色的逻辑
                this.showMessage(`角色 "${name}" 已保存`);
                this.closeModal();
            });
        }, 100);
    }

    // 场景设置
    setScene() {
        this.openModal('场景设置', `
            <div class="form-group">
                <label for="scene-name">场景名称:</label>
                <input type="text" id="scene-name" placeholder="输入场景名称">
            </div>
            <div class="form-group">
                <label for="scene-description">场景描述:</label>
                <textarea id="scene-description" placeholder="输入场景描述"></textarea>
            </div>
            <button id="save-scene-btn" class="btn">保存场景</button>
        `);
        
        // 绑定保存按钮事件
        setTimeout(() => {
            document.getElementById('save-scene-btn').addEventListener('click', () => {
                const name = document.getElementById('scene-name').value;
                const description = document.getElementById('scene-description').value;
                
                // 这里可以添加保存场景的逻辑
                this.showMessage(`场景 "${name}" 已保存`);
                this.closeModal();
            });
        }, 100);
    }

    // 变量设置
    setVariable() {
        this.openModal('变量设置', `
            <div class="form-group">
                <label for="variable-name">变量名称:</label>
                <input type="text" id="variable-name" placeholder="输入变量名称">
            </div>
            <div class="form-group">
                <label for="variable-type">变量类型:</label>
                <select id="variable-type">
                    <option value="string">字符串</option>
                    <option value="number">数字</option>
                    <option value="boolean">布尔值</option>
                </select>
            </div>
            <div class="form-group">
                <label for="variable-value">变量值:</label>
                <input type="text" id="variable-value" placeholder="输入变量值">
            </div>
            <button id="save-variable-btn" class="btn">保存变量</button>
        `);
        
        // 绑定保存按钮事件
        setTimeout(() => {
            document.getElementById('save-variable-btn').addEventListener('click', () => {
                const name = document.getElementById('variable-name').value;
                const type = document.getElementById('variable-type').value;
                const value = document.getElementById('variable-value').value;
                
                // 这里可以添加保存变量的逻辑
                this.showMessage(`变量 "${name}" (${type}) 已保存，值为: ${value}`);
                this.closeModal();
            });
        }, 100);
    }

    // 显示帮助
    showHelp() {
        this.openModal('使用帮助', `
            <h3>校园惊魂剧情编辑器使用指南</h3>
            <p>欢迎使用校园惊魂剧情编辑器！以下是基本使用方法：</p>
            <ul>
                <li><strong>文件菜单</strong>：新建、打开、保存和导出项目</li>
                <li><strong>编辑菜单</strong>：撤销、重做和删除节点</li>
                <li><strong>初始化设置</strong>：设置角色、场景和变量</li>
                <li><strong>剧情设置</strong>：添加对话、选项和事件节点</li>
                <li><strong>组件库</strong>：从右侧拖动组件到画布创建节点</li>
                <li><strong>属性面板</strong>：选中节点后编辑其属性</li>
            </ul>
            <h4>多选功能</h4>
            <ul>
                <li><strong>启用多选：</strong>按住Ctrl键</li>
                <li><strong>添加选择：</strong>Ctrl+点击节点</li>
                <li><strong>取消选择：</strong>Ctrl+点击已选节点</li>
                <li><strong>清空选择：</strong>点击空白处（不按Ctrl）</li>
                <li><strong>批量删除：</strong>多选后在右侧面板进行批量删除</li>
            </ul>
            <p>使用鼠标拖拽可以移动节点，双击节点可以编辑其属性。</p>
        `);
    }

    // 关于编辑器
    aboutEditor() {
        this.openModal('关于编辑器', `
            <h3>校园惊魂 - 剧情编辑器</h3>
            <p>版本: 1.0.0</p>
            <p>一个用于创建校园恐怖游戏剧情的可视化编辑器。</p>
            <p>使用此编辑器，您可以创建对话、选项和事件，构建完整的游戏剧情流程。</p>
            <p>© 2023 校园惊魂开发团队</p>
        `);
    }

    // 生成字符地图
    async generateMap() {
        const width = document.getElementById('map-width').value;
        const height = document.getElementById('map-height').value;
        const mapType = document.getElementById('map-type').value;
        const apiKey = document.getElementById('ai-api-key').value;

        if (!apiKey) {
            this.showMessage('请输入硅基流动AI API Key');
            return;
        }

        // 显示加载状态
        document.getElementById('generate-map-btn').textContent = '生成中...';
        document.getElementById('generate-map-btn').disabled = true;

        try {
            // 地图样例提示词，基于正式版游戏中的地图风格
            const mapExamples = {
                classroom: '🏫 教室地图样例：\n' +
                           '++++++++++++++\n' +
                           '+            +\n' +
                           '+  desks     +\n' +
                           '+  📚 📝    +\n' +
                           '+            +\n' +
                           '+      🖥️   +\n' +
                           '+            +\n' +
                           '++++++++++++++',
                corridor: '🚪 走廊地图样例：\n' +
                          '++++++++++++++\n' +
                          '+            +\n' +
                          '+  +------+  +\n' +
                          '+  |      |  +\n' +
                          '+  +------+  +\n' +
                          '+            +\n' +
                          '+  +------+  +\n' +
                          '+  |      |  +\n' +
                          '+  +------+  +\n' +
                          '+            +\n' +
                          '++++++++++++++',
                library: '📚 图书馆地图样例：\n' +
                         '++++++++++++++\n' +
                         '+  📚📚📚📚 +\n' +
                         '+  📚📚📚📚 +\n' +
                         '+            +\n' +
                         '+  📚📚📚📚 +\n' +
                         '+  📚📚📚📚 +\n' +
                         '+            +\n' +
                         '+  📚📚📚📚 +\n' +
                         '+  📚📚📚📚 +\n' +
                         '++++++++++++++',
                dormitory: '🛏️ 宿舍地图样例：\n' +
                           '++++++++++++++\n' +
                           '+  🛏️     🛏️ +\n' +
                           '+            +\n' +
                           '+  🚪        +\n' +
                           '+            +\n' +
                           '+  🛏️     🛏️ +\n' +
                           '++++++++++++++',
                canteen: '🍽️ 食堂地图样例：\n' +
                         '++++++++++++++\n' +
                         '+  🍽️🍽️🍽️  +\n' +
                         '+  🍽️🍽️🍽️  +\n' +
                         '+            +\n' +
                         '+  🍳        +\n' +
                         '+            +\n' +
                         '++++++++++++++',
                storageRoom: '🔒 仓库地图样例：\n' +
                             '++++++++++++++\n' +
                             '+  📦📦      +\n' +
                             '+  📦📦      +\n' +
                             '+            +\n' +
                             '+  📦📦      +\n' +
                             '+  📦📦      +\n' +
                             '++++++++++++++',
                labyrinth: '🌀 迷宫地图样例：\n' +
                           '++++++++++++++\n' +
                           '+  +--+--+   +\n' +
                           '+  |  |  |   +\n' +
                           '+--+  +--+   +\n' +
                           '+      |      +\n' +
                           '+  +--+--+   +\n' +
                           '+  |  |  |   +\n' +
                           '+  +--+--+   +\n' +
                           '++++++++++++++'
            };

            const selectedMapExample = mapExamples[mapType] || mapExamples.classroom;

            // 调用硅基流动AI API
            const response = await fetch('https://api.siliconflow.com/v1/chat/completions', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${apiKey}`
                },
                body: JSON.stringify({
                    model: 'gpt-3.5-turbo',
                    messages: [{
                        role: 'system',
                        content: '你是一个字符地图生成器，能够根据用户需求生成ASCII字符地图。地图应该包含墙(+)、地板( )、门(-或|)和适当的家具或物品。确保地图是闭合的，并且大小符合用户要求。'
                    }, {
                        role: 'user',
                        content: `生成一个${mapType}风格的字符地图，宽度为${width}，高度为${height}。参考以下样例风格：\n${selectedMapExample}`
                    }]
                })
            });

            if (!response.ok) {
                throw new Error('API调用失败');
            }

            const data = await response.json();
            const mapContent = data.choices[0].message.content;

            // 显示地图预览
            document.getElementById('map-preview').textContent = mapContent;
            this.editorState.currentGeneratedMap = mapContent;

            // 显示添加到节点按钮
            document.getElementById('add-map-to-node-btn').classList.remove('hidden');
        } catch (error) {
            console.error('生成地图失败:', error);
            this.showMessage('生成地图失败: ' + error.message);
        } finally {
            // 恢复按钮状态
            document.getElementById('generate-map-btn').textContent = '生成地图';
            document.getElementById('generate-map-btn').disabled = false;
        }
    }

    // 添加地图到节点
    addMapToNode() {
        if (!this.editorState.selectedNodeId || !this.editorState.currentGeneratedMap) {
            this.showMessage('请先选择一个节点并生成地图');
            return;
        }

        // 将地图添加到节点属性
        const node = this.editorState.nodes.find(n => n.id === this.editorState.selectedNodeId);
        if (node) {
            this.addHistoryState();
            node.mapContent = this.editorState.currentGeneratedMap;

            // 更新属性面板
            this.updatePropertiesPanel();

            // 隐藏地图生成器面板
            this.hideMapGeneratorPanel();

            this.showMessage('地图已成功添加到节点');
        }
    }
}

// 初始化编辑器
window.addEventListener('DOMContentLoaded', () => {
    const editor = new PlotEditor();

    // 添加地图生成器样式
    const style = document.createElement('style');
    style.textContent = `
        #map-generator-panel {
            padding: 15px;
            background: #2a2a2a;
            border-radius: 5px;
            color: white;
        }
        #map-generator-panel h3 {
            margin-top: 0;
            border-bottom: 1px solid #444;
            padding-bottom: 10px;
        }
        #map-generator-panel .form-group {
            margin-bottom: 15px;
        }
        #map-generator-panel label {
            display: block;
            margin-bottom: 5px;
        }
        #map-generator-panel input, #map-generator-panel select, #map-generator-panel textarea {
            width: 100%;
            padding: 8px;
            box-sizing: border-box;
            background: #3a3a3a;
            border: 1px solid #555;
            color: white;
            border-radius: 3px;
        }
        #map-preview-container {
            margin-top: 15px;
            max-height: 300px;
            overflow: auto;
            background: #1a1a1a;
            padding: 10px;
            border-radius: 3px;
        }
        #map-preview {
            white-space: pre;
            font-family: monospace;
            color: #ddd;
        }
        .btn {
            background: #4a6da7;
            color: white;
            border: none;
            padding: 8px 15px;
            border-radius: 3px;
            cursor: pointer;
            margin-right: 10px;
            margin-top: 10px;
        }
        .btn:hover {
            background: #5a7db7;
        }
        .hidden {
            display: none;
        }
    `;
    document.head.appendChild(style);
});